# -*- coding: iso-8859-15 -*-
import random
 
class Coordinator:
    def __init__(self):
        self.nodes = dict()
        self.commModel = None
    
    def setNodes(self, nodes):
        assert(len(nodes) > 1), 'Nodes must be >= 2'
        self.nodes = nodes
    
    def getNodes(self):
        return self.nodes
    
    def setTopology(self, topology = 'ring'):
        if topology == 'ring':
            iterator = self.nodes.iteritems()
            kprev, _ = iterator.next()
            first = kprev
            while(True):
                try:
                    knext, _ = iterator.next()
                    self.nodes[kprev] = knext
                    kprev = knext
                except StopIteration:
                    self.nodes[kprev] = first
                    break
        elif topology == 'connected':
            for node in self.nodes:
                neighbors = self.nodes.keys()
                neighbors.remove(node)
                self.nodes[node] = neighbors
        elif topology == 'random':
            nodes = self.nodes.keys()
            for node in self.nodes:
                neighbors = self.nodes.keys()
                neighbors.remove(node)
                howmany = int(random.uniform(1,len(self.nodes)-1))
                whom = []
                for x in range(howmany):
                    who = random.choice(neighbors)
                    neighbors.remove(who)
                    whom.append(who)
                self.nodes[node] = whom
        else:
            pass
    
    def _syncBroadcastModel(self):
        for sourceNode in self.nodes:
            msgBox = sourceNode.getOutbox()
            for dest, msg in msgBox:
                self.nodes[dest].addMessage(sourceNode, msg)
    
    def _assyncBroadcastModel(self):
        pass
    
    def _syncBroadcastRandomModel(self):
        pass
    
    def _assyncBroadcasrRandomModel(self):
        pass
        
    def setCommModel(self, model):
        assert model[0] == '_' and model in Coordinator.__dict__.keys(), \
        'Communication model must be a valid method of Coordinator'
        self.commModel = Coordinator.__dict__[model]
    
    def run(self, rounds):
        for r in range(rounds):
            print 'Round ', r
            for node in self.nodes:
                node.compute()
            
    
    def setInitObjects(self, initValueHolderObj, estimateValueHolderObj, functorObj, initializeObj):
        for node in self.nodes:
            print node, initValueHolderObj, estimateValueHolderObj, functorObj, initializeObj
            node.setInitValueHolder(initValueHolderObj)
            node.setEstimateHolder(estimateValueHolderObj)
            node.setFunctor(functorObj)
            node.setInitializer(initializeObj)
    def initializeNodes(self):
        for node in self.nodes:
            node.initialize()